From 228c2668d19d9691fba5fab4b6d84607a3b4a04a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 11 Mar 2006 10:47:55 +0100 Subject: [PATCH] Currently if one tries to execute VMX instruction from inside the VMX guest, the Xen hyper visor has no handling of it resulting in a bug(). This patch handles such VMX instructions from the guest returning invalid opcode to the guest. Also the macro VMX_INVALID_ERROR_CODE is renamed to the more meaningful VMX_DELIVER_NO_ERROR_CODE. Signed-Off-By: Nitin A Kamble Signed-Off-By: Jun Nakajima =20 --- xen/arch/x86/hvm/svm/intr.c | 2 +- xen/arch/x86/hvm/vmx/io.c | 2 +- xen/arch/x86/hvm/vmx/vmx.c | 19 ++++++++++++++++++- xen/include/asm-x86/hvm/support.h | 2 +- xen/include/asm-x86/hvm/vmx/vmx.h | 14 +++++++++++--- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/hvm/svm/intr.c b/xen/arch/x86/hvm/svm/intr.c index 33f1c42c06..430cad9372 100644 --- a/xen/arch/x86/hvm/svm/intr.c +++ b/xen/arch/x86/hvm/svm/intr.c @@ -187,7 +187,7 @@ asmlinkage void svm_intr_assist(void) } /* let's inject this interrupt */ TRACE_3D(TRC_VMX_INT, v->domain->domain_id, intr_vector, 0); - svm_inject_extint(v, intr_vector, VMX_INVALID_ERROR_CODE); + svm_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE); interrupt_post_injection(v, intr_vector, intr_type); break; case VLAPIC_DELIV_MODE_SMI: diff --git a/xen/arch/x86/hvm/vmx/io.c b/xen/arch/x86/hvm/vmx/io.c index 38ffa0a5d1..4727d65fee 100644 --- a/xen/arch/x86/hvm/vmx/io.c +++ b/xen/arch/x86/hvm/vmx/io.c @@ -165,7 +165,7 @@ asmlinkage void vmx_intr_assist(void) case VLAPIC_DELIV_MODE_EXT: case VLAPIC_DELIV_MODE_FIXED: case VLAPIC_DELIV_MODE_LPRI: - vmx_inject_extint(v, highest_vector, VMX_INVALID_ERROR_CODE); + vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE); TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0); break; case VLAPIC_DELIV_MODE_SMI: diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index ac169265f4..73037cc0d0 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -1917,7 +1917,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) /* don't bother H/W interrutps */ if (exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT && exit_reason != EXIT_REASON_VMCALL && - exit_reason != EXIT_REASON_IO_INSTRUCTION) + exit_reason != EXIT_REASON_IO_INSTRUCTION) HVM_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason); if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) { @@ -2052,6 +2052,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) __update_guest_eip(inst_len); break; } +#if 0 /* keep this for debugging */ case EXIT_REASON_VMCALL: __get_instruction_length(inst_len); __vmread(GUEST_RIP, &eip); @@ -2060,6 +2061,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) hvm_print_line(v, regs.eax); /* provides the current domain */ __update_guest_eip(inst_len); break; +#endif case EXIT_REASON_CR_ACCESS: { __vmread(GUEST_RIP, &eip); @@ -2100,6 +2102,21 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) case EXIT_REASON_MWAIT_INSTRUCTION: __hvm_bug(®s); break; + case EXIT_REASON_VMCALL: + case EXIT_REASON_VMCLEAR: + case EXIT_REASON_VMLAUNCH: + case EXIT_REASON_VMPTRLD: + case EXIT_REASON_VMPTRST: + case EXIT_REASON_VMREAD: + case EXIT_REASON_VMRESUME: + case EXIT_REASON_VMWRITE: + case EXIT_REASON_VMOFF: + case EXIT_REASON_VMON: + /* Report invalid opcode exception when a VMX guest tries to execute + any of the VMX instructions */ + vmx_inject_exception(v, TRAP_invalid_op, VMX_DELIVER_NO_ERROR_CODE); + break; + default: __hvm_bug(®s); /* should not happen */ } diff --git a/xen/include/asm-x86/hvm/support.h b/xen/include/asm-x86/hvm/support.h index b6f22e09ad..043754546a 100644 --- a/xen/include/asm-x86/hvm/support.h +++ b/xen/include/asm-x86/hvm/support.h @@ -99,7 +99,7 @@ enum hval_bitmaps { #define PC_DEBUG_PORT 0x80 -#define VMX_INVALID_ERROR_CODE -1 +#define VMX_DELIVER_NO_ERROR_CODE -1 /* * This works for both 32bit & 64bit eflags filteration diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index b5a4ced87f..f4429f3dbe 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -119,7 +119,15 @@ extern unsigned int cpu_rev; #define EXIT_REASON_RDPMC 15 #define EXIT_REASON_RDTSC 16 #define EXIT_REASON_VMCALL 18 - +#define EXIT_REASON_VMCLEAR 19 +#define EXIT_REASON_VMLAUNCH 20 +#define EXIT_REASON_VMPTRLD 21 +#define EXIT_REASON_VMPTRST 22 +#define EXIT_REASON_VMREAD 23 +#define EXIT_REASON_VMRESUME 24 +#define EXIT_REASON_VMWRITE 25 +#define EXIT_REASON_VMOFF 26 +#define EXIT_REASON_VMON 27 #define EXIT_REASON_CR_ACCESS 28 #define EXIT_REASON_DR_ACCESS 29 #define EXIT_REASON_IO_INSTRUCTION 30 @@ -425,7 +433,7 @@ static inline int __vmx_inject_exception(struct vcpu *v, int trap, int type, /* Reflect it back into the guest */ intr_fields = (INTR_INFO_VALID_MASK | type | trap); - if (error_code != VMX_INVALID_ERROR_CODE) { + if (error_code != VMX_DELIVER_NO_ERROR_CODE) { __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); intr_fields |= INTR_INFO_DELIEVER_CODE_MASK; } @@ -455,7 +463,7 @@ static inline int vmx_reflect_exception(struct vcpu *v) if (vector & INTR_INFO_DELIEVER_CODE_MASK) __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code); else - error_code = VMX_INVALID_ERROR_CODE; + error_code = VMX_DELIVER_NO_ERROR_CODE; vector &= 0xff; #ifndef NDEBUG -- 2.30.2